package com.conan.app.dailyflickr.app;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;

import com.conan.app.dailyflickr.AppData;
import com.conan.app.dailyflickr.app.BitmapHttpGet.QueueItem;

public class ImageDownloadTask extends AsyncTask<Void, Void, Void>{
	private static final String TAG = "ImageDownloadTask";
	public boolean isRunning = false;
	private boolean mConnected = true;
	
	private Context mContext;
	
	private ImageDownloadListener mListener;
	private HashMap<String, QueueItem> mQueueMap;
	private ArrayList<String> mPrepareGetUrl = new ArrayList<String>();
	
	public ImageDownloadTask(Context context){
		mContext = context;
		mQueueMap = new HashMap<String, QueueItem>();
	}
	
	public ImageDownloadTask(Context context, int position, String urlString, QueueItem queue){
		mContext = context;
		mQueueMap = new HashMap<String, QueueItem>();
		putToDownload(position, urlString, queue);
	}
	
	public void setListener(ImageDownloadListener listener){
		mListener = listener;
	}
	/**
	 * set internet connection flag to prevent download when no internet 
	 * @param flag
	 */
	public void setInternetConnection(boolean flag){
		mConnected = flag;
	}
	
	private void addUrlDownload(String urlString){
		if(mPrepareGetUrl.contains(urlString)) return;
    	synchronized (mPrepareGetUrl) {
			mPrepareGetUrl.add(urlString);
			
			mPrepareGetUrl.notifyAll();
		}
	}
    
	private void addFirstUrlDownload(String urlString){
		if(mPrepareGetUrl.contains(urlString)) return;
    	synchronized (mPrepareGetUrl) {    		
			mPrepareGetUrl.add(0, urlString);
			
			mPrepareGetUrl.notifyAll();
		}
	}
	
	/**
	 * get content when connect http
	 * @param urlString
	 * @return
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	private InputStream fetch(String urlString) throws MalformedURLException, IOException{
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpGet request = new HttpGet(urlString);
		HttpResponse response = httpClient.execute(request);
		return response.getEntity().getContent();
	}
	
	/**
	 * begin download from http
	 */
	private Bitmap fetchBitmap(String urlString){	
		Log.d(TAG, " image url: " + urlString);
		try{
			InputStream is = fetch(urlString);
			// TODO: save to sdcard later	
		
			Bitmap bitmap = BitmapFactory.decodeStream(is);
			
	        Log.d(TAG, "got a thumbnail drawable: " );
	        return bitmap;
	    } catch (MalformedURLException e) {
	        Log.e(TAG, "fetchBtimap failed", e);
	        return null;
	    } catch (IOException e) {
	        Log.e(TAG, "fetchBitmap failed", e);
	        return null;
	    }
	}
	/**
	 * add continue download when task is runninf
	 * @param urlString
	 * @param queue
	 */
	public void putToDownload(int position, String urlString, QueueItem queue){
		mQueueMap.put(urlString, queue);
		
		if(position < 0){			
			addFirstUrlDownload(urlString);
		}else{
			addUrlDownload(urlString);
		}
	}
	
	/**
	 * return number request download icon still not yet completed
	 * @param widgetId
	 * @return
	 */
	public int getRequests(int widgetId){
		if(mQueueMap == null) return 0;
		if(mQueueMap.size() < 1) return -1;
		int count = 0;
		for(String key: mQueueMap.keySet()){
			QueueItem item = mQueueMap.get(key);
			if(item.widgetId == widgetId) count ++;
		}
		return count;
	}	
	
	/**
	 * clear old request
	 */
	public void clearRequestBitmap(int widgetId){
		synchronized (mPrepareGetUrl) {
			mPrepareGetUrl.clear();
		}
	}
	
	/**
	 * clear request bitmap for main view
	 */
	public void clearMainBitmapItem(String url){
		synchronized (mQueueMap) {
			mPrepareGetUrl.remove(url);
			mQueueMap.remove(url);
		}		
	}
	
	
	@Override
	protected Void doInBackground(Void... params) {
		isRunning = true;
		     			
		while(!mPrepareGetUrl.isEmpty() && mConnected){
			//TODO : set imageView to a "pending" image
			
			String url = mPrepareGetUrl.remove(0);
			Bitmap bitmap = fetchBitmap(url);
			if( bitmap!= null ){
				QueueItem item = mQueueMap.remove(url);
				
				// save file to local storage
				if(item != null){
					if(item.position < 0){
						ApplicationUtils.storeBitmapFile(mContext, 
									String.format(AppData.IMAGE_PATTERN, item.widgetId, -1), 
									bitmap);
					}else{
						ApplicationUtils.storeBitmapFile(mContext, 
									String.format(AppData.IMAGE_PATTERN, item.page, item.id), 
									bitmap);
					}
					
					// pop item from dataCache 
					if(mListener != null){
						mListener.completed(item.widgetId, item.position, bitmap);
					}
				}    					

				Log.d(DailyPhotoData.TAG, "[download thread] done = " + mPrepareGetUrl.size());				
			}else{
				mPrepareGetUrl.add(url);
				Log.d(DailyPhotoData.TAG, "[download thread] fail" );
			}
    	}
		
		isRunning = false;
		return null;
	}
	
	@Override
	protected void onCancelled() {
		isRunning = false;
		mConnected = false;
		if(mQueueMap != null){
			mQueueMap.clear();
			mQueueMap = null;
		}
		
		if(mPrepareGetUrl != null){
			mPrepareGetUrl.clear();
			mPrepareGetUrl = null;
		}
		super.onCancelled();
	}
	
	public interface ImageDownloadListener{
		public void completed(int widgetId, int position, Bitmap bitmap); 
		
		// public void updateStatus();
	}
}


